package com.gdpu.pbss.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gdpu.pbss.Constants.Constants;
import com.gdpu.pbss.DTO.OrderDTO;
import com.gdpu.pbss.DTO.UserDto;
import com.gdpu.pbss.common.HoneyLogs;
import com.gdpu.pbss.common.LogType;
import com.gdpu.pbss.common.Result;
import com.gdpu.pbss.pojo.*;
import com.gdpu.pbss.service.OrderService;
import com.gdpu.pbss.service.PbService;
import com.gdpu.pbss.service.PbssService;
import com.gdpu.pbss.service.UserService;
import com.gdpu.pbss.utils.TokenUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;


import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.URLEncoder;
import java.sql.Timestamp;
import java.util.*;

import static net.sf.jsqlparser.util.validation.metadata.NamedObject.alias;

@RestController
@Slf4j
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private PbService pbService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private PbssService pbssService;

    @GetMapping("/")
    public List<User> userList(){
        return userService.getAllUser();
    }

    @GetMapping("/user/userId/{userId}")
    public Result getByid(@PathVariable("userId") Integer userId){
        User byId = userService.getById(userId);
        return Result.success(byId);
    }

      /*
      * 新增用户*/
    @HoneyLogs(operation = "用户管理",type = LogType.ADD)
    @PostMapping("/saveUser")
    public Boolean saveUser(@RequestBody User user){

           if (user.getUserId()==null){
               return userService.save(user);
           }else {
//               if (user.getBindStatus()==false){
//                   user.setBindStatus(false);
//               }
               Date date = new Date();
               Timestamp nuptime = new Timestamp(date.getTime());
               user.setUpdateTime(nuptime);
               log.info("user:"+user);
               return userService.updateById(user);
           }



    }

    @PostMapping("/bind")
    public Result bindUser(@RequestBody User user){

        log.info("-----------绑定的身份信息"+user);
        Date date = new Date();
        Timestamp nuptime = new Timestamp(date.getTime());
        user.setUpdateTime(nuptime);
        user.setBindStatus(true);

        return Result.success(userService.updateById(user));



    }

//    @PostMapping("/updateUser")
//    public Integer update(@RequestBody User user){
//        Date date = new Date();
//        Timestamp nuptime = new Timestamp(date.getTime());
//        user.setUpdateTime(nuptime);
//
//        log.info("user:"+user);
//        return  userService.updateU(user);
//
//    }

//    @HoneyLogs(operation = "用户管理",type = LogType.DELETE)
    @DeleteMapping("/deleteUser/{userId}")
    public Integer deleteUser(@PathVariable("userId") Integer userId){
        return userService.deleteUser(userId);
    }

    @HoneyLogs(operation = "用户管理",type = LogType.BATCH_DELETE)
    @PostMapping("/deleteBatch")
    public boolean deleteBatch(@RequestBody List<Integer> ids){
        return userService.removeByIds(ids);
    }

    @GetMapping("/user/page")
    public IPage<User> selectUserPage(@RequestParam Integer pageNum, @RequestParam Integer pageSize,
                                      @RequestParam(defaultValue = "") String userName,
                                      @RequestParam(defaultValue = "") Integer userId
                                     ){

//
//
//        Integer total = userService.selectTotal(userName);
//        List<User> userPage = userService.findUserPage(pageNum, pageSize,userName);
//        Map<String,Object>  res =new HashMap<String,Object>();
//
//        res.put("data",userPage);
//        res.put("total",total);
//        return res;
//         pageNum=(pageNum-1)*pageSize;


        IPage<User> page=new Page<>(pageNum,pageSize);

        QueryWrapper<User> qw =new QueryWrapper<>();


            qw.eq(userId!=null,"user_id",userId);



//        qw.and(
//                wrapper -> wrapper.like(userName!=null,"user_name",userName).or().like(phone!=null,"phone",phone)
//                        );

            qw.like(userName!=null,"user_name",userName);

            qw.orderByDesc("create_time");

//        Manager manager= TokenUtils.getManager();
//        System.out.println(manager.getManageName());


        return userService.page(page,qw);

    }

    @GetMapping("/export")
    public void export(HttpServletResponse response) throws Exception {
// 从数据库查询出所有的数据
        List<User> list = userService.list();//在内存操作，写出到浏览器
        ExcelWriter writer = ExcelUtil.getWriter(true);//自定义标题别名
        writer.addHeaderAlias("userName", "用户名");
        writer.addHeaderAlias("passward", "密码");
        writer.addHeaderAlias("userId", "用户id");
        writer.addHeaderAlias("phone", "手机");
        writer.addHeaderAlias("address", "地址");
        writer.addHeaderAlias("updateTime", "更新时间");
        writer.addHeaderAlias("createTime","创建时间");

        writer.write(list,true);

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        String fileName= URLEncoder.encode("用户信息", "UTF-8");
        response.setHeader("Content-Disposition","attachment;filename="+fileName+".xlsx");

        ServletOutputStream out =response.getOutputStream();
        writer.flush(out,true);
        out.close();
        writer.close();
    }

    @PostMapping("/import")
    public Result imp(MultipartFile file) throws Exception{
        InputStream inputStream=file.getInputStream();
        ExcelReader reader=ExcelUtil.getReader(inputStream);


        List<List<Object>> list = reader.read(1);
        List<User> users= CollUtil.newArrayList();

        List<User> userList = userService.list();
        for (List<Object> row : list) {
            User user =new User();
            for (User user1 : userList) {
                if (row.get(0).toString().equals(user1.getUserName())){
                    return Result.error("400","用户名重复");
                }
            }

            user.setUserName(row.get(0).toString());
            user.setPassward(row.get(1).toString());
            user.setPhone(row.get(2).toString());
            user.setAddress(row.get(3).toString());


            users.add(user);
        }
        userService.saveBatch(users);
        return Result.success();
    }
    @HoneyLogs(operation = "用户",type = LogType.LOGIN)
    @PostMapping("/user/login")
    public Result userlogin(@RequestBody UserDto userDto){

      String un=userDto.getUserName();
      String up=userDto.getPassward();
       log.info(up+un);
      if (StrUtil.isBlank(un)||StrUtil.isBlank(up)){
          return Result.error(Constants.CODE_500,"用户参数错误");
      }

          UserDto userDto1 = userService.login(userDto);
          StpUtil.login(10002);
          return Result.success(userDto1);
    }


    @GetMapping("/isLogin")
    public String isLogin() {
        System.out.println("当前会话是否登录：" + StpUtil.isLogin());
        return "当前会话是否登录：" + StpUtil.isLogin();
    }

    @PostMapping("/user/register")
    public Result userRegister(@RequestBody UserDto userDto){
        String un=userDto.getUserName();
        String up=userDto.getPassward();
        if (StrUtil.isBlank(un)||StrUtil.isBlank(up)){
            return Result.error(Constants.CODE_500,"用户参数错误");
        }
        return Result.success(userService.register(userDto));
    }

    @GetMapping("/user/userName/{userName}")
    public Result getUserByname(@PathVariable("userName") String userName){
        QueryWrapper<User> qw=new QueryWrapper<>();
        qw.eq("user_name",userName);
       return Result.success(userService.getOne(qw)) ;
    }

    @GetMapping("/user/IdCard/{IdCard}")
    public Result getUserByname(@PathVariable("IdCard") Integer IdCard){
        QueryWrapper<User> qw=new QueryWrapper<>();
        qw.eq("id_card",IdCard);
        return Result.success(userService.getOne(qw)) ;
    }

    @GetMapping("/user/pbPage")
    public Result selectPbPage(@RequestParam Integer pageNum, @RequestParam Integer pageSize,
                               @RequestParam(defaultValue = "") Integer pbId,
                               @RequestParam(defaultValue = "")  Integer pbssId
    )
    {


        IPage<Pb> page=new Page<>(pageNum,pageSize);
        QueryWrapper<Pb> qw =new QueryWrapper<>();
        qw.eq("enable",true);

        qw.eq(pbssId!=null,"pbss_id",pbssId);
        qw.eq(pbId!=null,"pb_id",pbId);
//        if (!"".equals(pbssName)) {
//            qw.like("pbss_name", pbssName);
//        }
        qw.orderByDesc("pb_id");


        return Result.success(pbService.page(page,qw));

    }

    @PostMapping("/user/Pb/sendDirect")
    public Result sendDirect(@RequestBody Order order){

        QueryWrapper<Pb> qw=new QueryWrapper<>();
        qw.eq("pb_name",order.getPbName());
        Pb pbone = pbService.getOne(qw);
        if (pbone.getPbStatus()==true){
            return Result.error(Constants.CODE_600,"该充电宝已被租借");
        }


        User user = TokenUtils.getUser();
        Double naccount=user.getAccount()-pbone.getPbPrice();
        if(naccount<=0){
            return Result.error(Constants.CODE_500,"余额不足");
        }
        user.setAccount(naccount);
        userService.updateById(user);

        pbone.setPbStatus(true);
        pbService.updateById(pbone);

        QueryWrapper<Pbss> PbssQw =new QueryWrapper<>();
        PbssQw.eq("pbss_name",order.getPbssName());
        Pbss pbssOne = pbssService.getOne(PbssQw);
        pbssOne.setSendCount(pbssOne.getSendCount()+1);
        pbssOne.setPbCount(pbssOne.getPbCount()-1);
        pbssService.updateById(pbssOne);


        System.out.println("确认订单信息-----------"+order);

        return Result.success( orderService.save(order));
    }


    @PostMapping("/user/Pb/sendNone")
    public Result sendNone(@RequestBody Order order){

        if (TokenUtils.getUser().getBindStatus()==false){
            return Result.error();
        }
        QueryWrapper<Pb> qw=new QueryWrapper<>();
        qw.eq("pb_name",order.getPbName());
        Pb pbone = pbService.getOne(qw);
        if (pbone.getPbStatus()==true){
            return Result.error(Constants.CODE_600,"该充电宝已被租借");
        }


        User user = TokenUtils.getUser();
        Double naccount=user.getAccount()-pbone.getPbPrice();
        if(naccount<=0){
            return Result.error(Constants.CODE_500,"余额不足");
        }
        user.setAccount(naccount);
        userService.updateById(user);

        pbone.setPbStatus(true);
        pbService.updateById(pbone);

        QueryWrapper<Pbss> PbssQw =new QueryWrapper<>();
        PbssQw.eq("pbss_name",order.getPbssName());
        Pbss pbssOne = pbssService.getOne(PbssQw);
        pbssOne.setSendCount(pbssOne.getSendCount()+1);
        pbssOne.setPbCount(pbssOne.getPbCount()-1);
        pbssService.updateById(pbssOne);


        System.out.println("确认订单信息-----------"+order);
        order.setPayStyle(true);
        return Result.success( orderService.save(order));
    }

    @GetMapping("/user/order/nowPage")
    public Result selectOrderNowPage(@RequestParam Integer pageNum, @RequestParam Integer pageSize
    )
    {


        IPage<Order> page=new Page<>(pageNum,pageSize);
        QueryWrapper<Order> qw =new QueryWrapper<>();


        qw.like(TokenUtils.getUser().getUserName()!=null,"user_name",TokenUtils.getUser().getUserName());
//        if (!"".equals(pbssName)) {
//            qw.like("pbss_name", pbssName);
//        }
        qw.eq("order_status",false);
        qw.orderByDesc("create_time");


        return Result.success(orderService.page(page,qw));

    }

    @PostMapping("/user/order/sendBack")
    public Result sendBack(@RequestBody Order order){
        if (order!=null){
            Date date = new Date();
            Timestamp nuptime = new Timestamp(date.getTime());
            order.setEndTime(nuptime);
            order.setOrderStatus(true);
            orderService.updateById(order);

            QueryWrapper<Pb> pbqw=new QueryWrapper<>();
            pbqw.eq("pb_name",order.getPbName());
            Pb pbone = pbService.getOne(pbqw);
            pbone.setPbStatus(false);
            pbone.setPbssName(order.getPbssName());
            pbService.updateById(pbone);




            QueryWrapper<Pbss> pbssQW=new QueryWrapper<>();
            pbssQW.eq("pbss_name",order.getPbssName());
            Pbss pbssOne = pbssService.getOne(pbssQW);
            pbssOne.setPbCount(pbssOne.getPbCount()+1);
            pbssService.updateById(pbssOne);


        }
        return Result.success(order);

    }

    @GetMapping("/user/order/historyPage")
    public Result historyPage(@RequestParam Integer pageNum, @RequestParam Integer pageSize

    )
    {


        IPage<Order> page=new Page<>(pageNum,pageSize);
        QueryWrapper<Order> qw =new QueryWrapper<>();


        qw.like(TokenUtils.getUser().getUserName()!=null,"user_name",TokenUtils.getUser().getUserName());
        qw.eq("order_status",true);
        qw.orderByDesc("end_time");

//        log.info("当前用户信息---------------------------"+TokenUtils.getUser());
        return Result.success(orderService.page(page,qw));

    }
    @PostMapping ("/user/account/recharge")

    public Result rechargeAccount(@RequestBody User user){
        Double rechargeAcount = user.getAccount();
        if (rechargeAcount>0){
            User user1 = TokenUtils.getUser();
            Double naccount= user1.getAccount()+rechargeAcount;
            user1.setAccount(naccount);
            userService.updateById(user1);
            return Result.success("充值成功");
        }

        return Result.error(Constants.CODE_600,"充值失败");


    }






}
